package com.itheima.pinda.filter;

import cn.hutool.core.util.StrUtil;
import com.itheima.pinda.base.R;
import com.itheima.pinda.common.adapter.IgnoreTokenConfig;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletRequest;

/**
 * 公共过滤器, 抽取一些方法
 *
 * @author llhuang10
 * @date 2021/8/29 21:03
 */
@Slf4j
public abstract class BaseFilter extends ZuulFilter {

    @Value("${server.servlet.context-path}")
    protected String zuulPrefix;      //  /api


    /**
     * 判断当前请求uri是否需要忽略 (直接放行, 就是不进行jwt解析和鉴权)
     *
     * @return true表示需要放行
     */
    protected boolean isIgnoreToken() {
        // 动态获取当前请求的uri
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String uri = request.getRequestURI();

        // 原始的uri   /api/file/user/list  截取 --> /file/user/list
        uri = StrUtil.subSuf(uri, zuulPrefix.length());
        //  /file/user/list  截取 --> /user/list

        // uri.indexOf("/", 1) --> 这里的 1 表示字符串 / 出现在 uri 第二次的位置
        uri = StrUtil.subSuf(uri, uri.indexOf("/", 1));

        boolean ignoreToken = IgnoreTokenConfig.isIgnoreToken(uri);
        return ignoreToken;
    }

    //

    /**
     * 网关抛异常, 不再进行路由, 而是直接返回前端
     *
     * @param errMsg         错误信息
     * @param errCode        错误码
     * @param httpStatusCode http状态码
     */
    protected void errorResponse(String errMsg, int errCode, int httpStatusCode) {
        RequestContext requestContext = RequestContext.getCurrentContext();
        // 设置响应状态码
        requestContext.setResponseStatusCode(httpStatusCode);

        // 设置响应头信息      MediaType.APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8"
        requestContext.addZuulResponseHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
        if (requestContext.getResponseBody() == null) {
            // 设置响应体中错误内容
            requestContext.setResponseBody(R.fail(errCode, errMsg).toString());
            // 不进行路由, 直接返回
            requestContext.setSendZuulResponse(false);
        }
    }
}
